<template>
	<div class="game-container">
		<!-- 触摸区域 - 仅覆盖游戏主界面，避免影响按钮 -->
		<div class="touch-area" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd">
			<!-- 游戏头部 -->
			<header class="game-header">
				<div class="game-title">
					<span class="title-primary">东版</span>
					<span class="title-number">2048</span>
				</div>
				
				<div class="score-container">
					<div class="score-card">
						<p class="score-label">得分</p>
						<p class="score-value">{{ grade }}</p>
					</div>
					<div class="score-card">
						<p class="score-label">最高分</p>
						<p class="score-value">{{ historyGrade }}</p>
					</div>
				</div>
			</header>
			
			<!-- 游戏主界面 -->
			<div class="game-board">
				<div class="board-grid">
					<div v-for="(row, rowIndex) in array" :key="rowIndex" class="board-row">
						<div 
							v-for="(cell, colIndex) in row" 
							:key="colIndex" 
							class="board-cell"
						>
							<div 
								class="cell-value"
								:class="{ 
									'cell-2': cell === 2,
									'cell-4': cell === 4,
									'cell-8': cell === 8,
									'cell-16': cell === 16,
									'cell-32': cell === 32,
									'cell-64': cell === 64,
									'cell-128': cell === 128,
									'cell-256': cell === 256,
									'cell-512': cell === 512,
									'cell-1024': cell === 1024,
									'cell-2048': cell === 2048,
									'new-cell': coordinate === `${rowIndex},${colIndex}`,
									'merged-cell': mergedCells.includes(`${rowIndex},${colIndex}`)
								}"
							>
								{{ cell !== 0 ? cell : '' }}
							</div>
						</div>
					</div>
				</div>
			</div>
			
			<!-- 游戏提示 -->
			<div class="game-hint">
				<p>滑动屏幕移动方块，相同数字碰撞将合并</p>
			</div>
		</div>
		
		<!-- 游戏操作区 - 移至底部 -->
		<div class="game-controls">
			<button class="control-btn reset-btn" @click.stop="anew">
				<i class="fas fa-redo"></i> 重新开始
			</button>
			<button class="control-btn rank-btn" @click.stop="lookRanking">
				<i class="fas fa-trophy"></i> 排行榜
			</button>
		</div>
		
		<!-- 游戏结束弹窗 -->
		<div class="game-modal" v-if="gameOver">
			<div class="modal-content">
				<h2 class="modal-title">游戏结束!</h2>
				<p class="modal-score">最终得分: <span>{{ grade }}</span></p>
				<div class="modal-buttons">
					<button class="modal-btn restart-btn" @click="anew">再玩一次</button>
					<button class="modal-btn exit-btn" @click="goBack">退出游戏</button>
				</div>
			</div>
		</div>
		
		<!-- 排行榜弹窗 -->
		<van-popup 
			:show="showRanking" 
			@close="showRanking = false" 
			position="bottom" 
			custom-style="height: 80%; border-radius: 20rpx 20rpx 0 0;"
		>
			<div class="ranking-header">
				<h3>排行榜</h3>
			</div>
			<ul class="ranking-list">
				<van-empty description="暂无游戏记录" v-if="rankingList.length === 0" />
				<li v-for="(item, index) in rankingList" :key="index" class="ranking-item">
					<div class="rank-number" :class="index < 3 ? 'top-rank' : ''">
						{{ index + 1 }}
					</div>
					<div class="rank-avatar">
						<image :src="item.headImage || defaultAvatar" mode="widthFix"></image>
					</div>
					<div class="rank-info">
						<p class="rank-name">{{ item.nickname || '匿名玩家' }}</p>
						<p class="rank-signature">{{ item.ramk || '无签名' }}</p>
					</div>
					<div class="rank-score">{{ item.grade }}</div>
				</li>
			</ul>
		</van-popup>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				// 游戏核心数据
				array: Array(5).fill().map(() => Array(5).fill(0)),
				grade: 0,
				historyGrade: 0,
				gameOver: false,
				
				// 触摸事件相关
				startX: 0,
				startY: 0,
				endX: 0,
				endY: 0,
				isMoving: false,
				
				// 动画相关 - 减少动画持续时间
				coordinate: '',
				mergedCells: [],
				
				// 排行榜相关
				showRanking: false,
				rankingList: [],
				userInfo: {},
				historyObj: {},
				
				// 默认头像
				defaultAvatar: 'https://picsum.photos/id/64/200/200'
			};
		},
		
		onLoad() {
			// 初始化用户信息
			this.userInfo = uni.getStorageSync('userInfo') || {};
			
			// 加载缓存数据
			const cachedGame = uni.getStorageSync('cache_2048');
			if (cachedGame) {
				this.array = cachedGame;
				this.grade = uni.getStorageSync('grade') * 1 || 0;
			} else {
				// 初始化新游戏
				this.initializeGame();
			}
		},
		
		onShow() {
			// 获取用户历史最高分
			this.loadUserBestScore();
		},
		
		beforeDestroy() {
			// 游戏未结束时保存当前状态
			if (!this.gameOver) {
				uni.setStorageSync('cache_2048', this.array);
				uni.setStorageSync('grade', this.grade);
			} else {
				// 游戏结束时清除缓存
				uni.removeStorageSync('cache_2048');
				uni.removeStorageSync('grade');
			}
		},
		
		methods: {
			// 初始化游戏
			initializeGame() {
				this.array = Array(5).fill().map(() => Array(5).fill(0));
				this.grade = 0;
				this.gameOver = false;
				
				// 初始生成两个数字 - 移除初始动画延迟
				this.generateRandomNumber();
				this.generateRandomNumber();
			},
			
			// 生成随机数字
			generateRandomNumber() {
				// 查找空位置
				const emptyCells = [];
				for (let i = 0; i < 5; i++) {
					for (let j = 0; j < 5; j++) {
						if (this.array[i][j] === 0) {
							emptyCells.push({ x: i, y: j });
						}
					}
				}
				
				if (emptyCells.length === 0) return false;
				
				// 随机选择一个空位置
				const { x, y } = emptyCells[Math.floor(Math.random() * emptyCells.length)];
				
				// 随机生成2或4
				const value = Math.random() < 0.9 ? 2 : 4;
				
				// 添加新方块动画标记
				this.coordinate = `${x},${y}`;
				
				// 设置数值 - 缩短动画延迟时间
				setTimeout(() => {
					this.array[x][y] = value;
					this.coordinate = '';
					
					// 检查游戏是否结束
					this.checkGameOver();
				}, 50); // 从100ms缩短到50ms
				
				return true;
			},
			
			// 检查游戏是否结束
			checkGameOver() {
				// 检查是否有空位置
				for (let i = 0; i < 5; i++) {
					for (let j = 0; j < 5; j++) {
						if (this.array[i][j] === 0) {
							return false;
						}
					}
				}
				
				// 检查是否还有可合并的方块
				if (this.canMerge()) {
					return false;
				}
				
				// 游戏结束
				this.gameOver = true;
				this.saveScore();
				return true;
			},
			
			// 检查是否还有可合并的方块
			canMerge() {
				// 检查水平方向
				for (let i = 0; i < 5; i++) {
					for (let j = 0; j < 4; j++) {
						if (this.array[i][j] === this.array[i][j + 1]) {
							return true;
						}
					}
				}
				
				// 检查垂直方向
				for (let j = 0; j < 5; j++) {
					for (let i = 0; i < 4; i++) {
						if (this.array[i][j] === this.array[i + 1][j]) {
							return true;
						}
					}
				}
				
				return false;
			},
			
			// 触摸开始事件
			onTouchStart(e) {
				if (this.gameOver) return;
				this.startX = e.touches[0].clientX;
				this.startY = e.touches[0].clientY;
				this.isMoving = true;
				this.mergedCells = [];
			},
			
			// 触摸移动事件
			onTouchMove(e) {
				if (!this.isMoving || this.gameOver) return;
				this.endX = e.touches[0].clientX;
				this.endY = e.touches[0].clientY;
			},
			
			// 触摸结束事件
			onTouchEnd() {
				if (!this.isMoving || this.gameOver) return;
				this.isMoving = false;
				
				// 计算移动距离
				const deltaX = this.endX - this.startX;
				const deltaY = this.endY - this.startY;
				
				// 判断滑动方向（优先处理水平或垂直方向更明显的滑动）
				if (Math.abs(deltaX) > Math.abs(deltaY)) {
					// 水平滑动
					if (Math.abs(deltaX) > 50) {
						deltaX > 0 ? this.moveRight() : this.moveLeft();
					}
				} else {
					// 垂直滑动
					if (Math.abs(deltaY) > 50) {
						deltaY > 0 ? this.moveDown() : this.moveUp();
					}
				}
			},
			
			// 向左移动
			moveLeft() {
				const oldArray = JSON.parse(JSON.stringify(this.array));
				
				for (let i = 0; i < 5; i++) {
					// 合并相同数字
					for (let j = 1; j < 5; j++) {
						if (this.array[i][j] !== 0) {
							let k = j;
							// 向左移动直到遇到非零数字或边界
							while (k > 0 && this.array[i][k - 1] === 0) {
								this.array[i][k - 1] = this.array[i][k];
								this.array[i][k] = 0;
								k--;
							}
							
							// 检查是否可以合并
							if (k > 0 && this.array[i][k - 1] === this.array[i][k]) {
								this.array[i][k - 1] *= 2;
								this.grade += this.array[i][k - 1];
								this.mergedCells.push(`${i},${k - 1}`);
								this.array[i][k] = 0;
							}
						}
					}
				}
				
				// 如果数组发生变化，生成新数字 - 缩短延迟
				if (!this.arraysEqual(oldArray, this.array)) {
					setTimeout(() => this.generateRandomNumber(), 100); // 从200ms缩短到100ms
				}
			},
			
			// 向右移动
			moveRight() {
				const oldArray = JSON.parse(JSON.stringify(this.array));
				
				for (let i = 0; i < 5; i++) {
					// 合并相同数字
					for (let j = 3; j >= 0; j--) {
						if (this.array[i][j] !== 0) {
							let k = j;
							// 向右移动直到遇到非零数字或边界
							while (k < 4 && this.array[i][k + 1] === 0) {
								this.array[i][k + 1] = this.array[i][k];
								this.array[i][k] = 0;
								k++;
							}
							
							// 检查是否可以合并
							if (k < 4 && this.array[i][k + 1] === this.array[i][k]) {
								this.array[i][k + 1] *= 2;
								this.grade += this.array[i][k + 1];
								this.mergedCells.push(`${i},${k + 1}`);
								this.array[i][k] = 0;
							}
						}
					}
				}
				
				// 如果数组发生变化，生成新数字 - 缩短延迟
				if (!this.arraysEqual(oldArray, this.array)) {
					setTimeout(() => this.generateRandomNumber(), 100); // 从200ms缩短到100ms
				}
			},
			
			// 向上移动
			moveUp() {
				const oldArray = JSON.parse(JSON.stringify(this.array));
				
				for (let j = 0; j < 5; j++) {
					// 合并相同数字
					for (let i = 1; i < 5; i++) {
						if (this.array[i][j] !== 0) {
							let k = i;
							// 向上移动直到遇到非零数字或边界
							while (k > 0 && this.array[k - 1][j] === 0) {
								this.array[k - 1][j] = this.array[k][j];
								this.array[k][j] = 0;
								k--;
							}
							
							// 检查是否可以合并
							if (k > 0 && this.array[k - 1][j] === this.array[k][j]) {
								this.array[k - 1][j] *= 2;
								this.grade += this.array[k - 1][j];
								this.mergedCells.push(`${k - 1},${j}`);
								this.array[k][j] = 0;
							}
						}
					}
				}
				
				// 如果数组发生变化，生成新数字 - 缩短延迟
				if (!this.arraysEqual(oldArray, this.array)) {
					setTimeout(() => this.generateRandomNumber(), 100); // 从200ms缩短到100ms
				}
			},
			
			// 向下移动
			moveDown() {
				const oldArray = JSON.parse(JSON.stringify(this.array));
				
				for (let j = 0; j < 5; j++) {
					// 合并相同数字
					for (let i = 3; i >= 0; i--) {
						if (this.array[i][j] !== 0) {
							let k = i;
							// 向下移动直到遇到非零数字或边界
							while (k < 4 && this.array[k + 1][j] === 0) {
								this.array[k + 1][j] = this.array[k][j];
								this.array[k][j] = 0;
								k++;
							}
							
							// 检查是否可以合并
							if (k < 4 && this.array[k + 1][j] === this.array[k][j]) {
								this.array[k + 1][j] *= 2;
								this.grade += this.array[k + 1][j];
								this.mergedCells.push(`${k + 1},${j}`);
								this.array[k][j] = 0;
							}
						}
					}
				}
				
				// 如果数组发生变化，生成新数字 - 缩短延迟
				if (!this.arraysEqual(oldArray, this.array)) {
					setTimeout(() => this.generateRandomNumber(), 100); // 从200ms缩短到100ms
				}
			},
			
			// 比较两个二维数组是否相等
			arraysEqual(arr1, arr2) {
				return JSON.stringify(arr1) === JSON.stringify(arr2);
			},
			
			// 重新开始游戏
			anew() {
				this.initializeGame();
				this.loadUserBestScore();
			},
			
			// 返回上一页
			goBack() {
				uni.navigateBack({ delta: 1 });
			},
			
			// 查看排行榜
			async lookRanking() {
				try {
					const result = await this.$axios('overallSituation', {
						state: 'look',
						databaseName: "play_2048"
					});
					
					// 按分数排序
					this.rankingList = result.data.sort((a, b) => b.grade - a.grade);
					this.showRanking = true;
				} catch (error) {
					console.error('获取排行榜失败:', error);
					this.$showToast('获取排行榜失败', 'error');
				}
			},
			
			// 加载用户最佳分数
			async loadUserBestScore() {
				if (!this.userInfo.userName) return;
				
				try {
					const result = await this.$axios('overallSituation', {
						state: 'look',
						databaseName: "play_2048",
						userName: this.userInfo.userName
					});
					
					if (result.data.length) {
						this.historyGrade = result.data[0].grade;
						this.historyObj = result.data[0];
					} else {
						this.historyGrade = 0;
						this.historyObj = {};
					}
				} catch (error) {
					console.error('获取用户最佳分数失败:', error);
				}
			},
			
			// 保存分数
			async saveScore() {
				if (!this.userInfo.userName) return;
				
				// 只在新分数高于历史最高分才保存
				if (this.grade <= this.historyGrade) return;
				
				try {
					const params = this.historyObj._id 
						? {
							state: 'update',
							databaseName: "play_2048",
							...this.userInfo,
							grade: this.grade,
							_id: this.historyObj._id
						} 
						: {
							state: 'add',
							databaseName: "play_2048",
							...this.userInfo,
							grade: this.grade
						};
					
					await this.$axios('overallSituation', params);
					this.loadUserBestScore(); // 更新显示的最高分
				} catch (error) {
					console.error('保存分数失败:', error);
				}
			}
		}
	};
</script>

<style scoped>
	/* 基础样式 */
	.game-container {
		width: 100%;
		min-height: 100vh;
		background-color: #faf8ef;
		padding: 20rpx;
		box-sizing: border-box;
		font-family: 'Clear Sans', 'Helvetica Neue', Arial, sans-serif;
		display: flex;
		flex-direction: column;
	}
	
	/* 触摸区域限制 - 解决按钮点击触发滑动问题 */
	.touch-area {
		flex: 1;
	}
	
	/* 头部样式 */
	.game-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 30rpx;
		padding: 0 10rpx;
	}
	
	.game-title {
		display: flex;
		align-items: center;
	}
	
	.title-primary {
		font-size: 60rpx;
		font-weight: bold;
		color: #c12c1f;
		margin-right: 10rpx;
	}
	
	.title-number {
		font-size: 50rpx;
		font-weight: bold;
		color: #776e65;
	}
	
	.score-container {
		display: flex;
		gap: 15rpx;
	}
	
	.score-card {
		background-color: #bbada0;
		border-radius: 8rpx;
		padding: 10rpx 20rpx;
		min-width: 120rpx;
		text-align: center;
		box-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
	}
	
	.score-label {
		font-size: 24rpx;
		color: #eee4da;
		margin: 0;
	}
	
	.score-value {
		font-size: 36rpx;
		font-weight: bold;
		color: white;
		margin: 0;
	}
	
	/* 操作按钮样式 - 移至底部并美化 */
	.game-controls {
		display: flex;
		justify-content: center;
		gap: 30rpx;
		padding: 20rpx 0;
		width: 100%;
		box-sizing: border-box;
	}
	
	.control-btn {
		color: #f9f6f2;
		border: none;
		border-radius: 12rpx;
		padding: 20rpx 40rpx;
		font-size: 30rpx;
		font-weight: bold;
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 15rpx;
		cursor: pointer;
		transition: all 0.3s ease;
		box-shadow: 0 4rpx 8rpx rgba(0,0,0,0.15);
		flex: 1;
		max-width: 300rpx;
	}
	
	.control-btn:hover {
		transform: translateY(-2rpx);
		box-shadow: 0 6rpx 12rpx rgba(0,0,0,0.2);
	}
	
	.control-btn:active {
		transform: translateY(0);
		box-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
	}
	
	.reset-btn {
		background: linear-gradient(135deg, #8f7a66, #776354);
	}
	
	.rank-btn {
		background: linear-gradient(135deg, #ff7f50, #e06a3e);
	}
	
	/* 游戏板样式 */
	.game-board {
		background-color: #bbada0;
		border-radius: 16rpx;
		padding: 20rpx;
		margin-bottom: 30rpx;
		box-shadow: 0 8rpx 16rpx rgba(0,0,0,0.1);
	}
	
	.board-grid {
		display: flex;
		flex-direction: column;
		gap: 15rpx;
	}
	
	.board-row {
		display: flex;
		gap: 15rpx;
	}
	
	.board-cell {
		flex: 1;
		height: 140rpx;
		background-color: rgba(238, 228, 218, 0.35);
		border-radius: 8rpx;
		display: flex;
		align-items: center;
		justify-content: center;
	}
	
	.cell-value {
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 48rpx;
		font-weight: bold;
		transition: all 0.15s ease; /* 缩短过渡时间 */
		border-radius: 8rpx;
	}
	
	/* 方块颜色样式 */
	.cell-2 {
		background-color: #eee4da;
		color: #776e65;
	}
	
	.cell-4 {
		background-color: #ede0c8;
		color: #776e65;
	}
	
	.cell-8 {
		background-color: #f2b179;
		color: #f9f6f2;
	}
	
	.cell-16 {
		background-color: #f59563;
		color: #f9f6f2;
	}
	
	.cell-32 {
		background-color: #f67c5f;
		color: #f9f6f2;
	}
	
	.cell-64 {
		background-color: #f65e3b;
		color: #f9f6f2;
	}
	
	.cell-128 {
		background-color: #edcf72;
		color: #f9f6f2;
		box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
	}
	
	.cell-256 {
		background-color: #edcc61;
		color: #f9f6f2;
		box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.15);
	}
	
	.cell-512 {
		background-color: #edc850;
		color: #f9f6f2;
		box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.2);
	}
	
	.cell-1024 {
		background-color: #edc53f;
		color: #f9f6f2;
		box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.25);
		font-size: 36rpx !important;
	}
	
	.cell-2048 {
		background-color: #edc22e;
		color: #f9f6f2;
		box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.3);
		font-size: 36rpx !important;
	}
	
	/* 优化动画效果 - 减弱动画强度 */
	.new-cell {
		animation: appear 0.15s ease-out; /* 缩短动画时间并使用更平缓的曲线 */
	}
	
	.merged-cell {
		animation: merge 0.15s ease-out; /* 缩短动画时间并使用更平缓的曲线 */
	}
	
	/* 减弱新方块出现动画 */
	@keyframes appear {
		0% {
			transform: scale(0.8); /* 缩小幅度减小 */
			opacity: 0.5; /* 初始透明度提高 */
		}
		100% {
			transform: scale(1);
			opacity: 1;
		}
	}
	
	/* 减弱合并动画 */
	@keyframes merge {
		0% {
			transform: scale(1);
		}
		50% {
			transform: scale(1.05); /* 放大幅度减小 */
		}
		100% {
			transform: scale(1);
		}
	}
	
	/* 游戏提示 */
	.game-hint {
		text-align: center;
		color: #776e65;
		font-size: 28rpx;
		margin-bottom: 40rpx;
	}
	
	/* 游戏结束弹窗 */
	.game-modal {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: rgba(238, 228, 218, 0.73);
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 1000;
	}
	
	.modal-content {
		background-color: white;
		border-radius: 16rpx;
		padding: 60rpx 40rpx;
		text-align: center;
		width: 80%;
		max-width: 500rpx;
		box-shadow: 0 10rpx 20rpx rgba(0,0,0,0.2);
	}
	
	.modal-title {
		font-size: 50rpx;
		font-weight: bold;
		color: #776e65;
		margin-bottom: 20rpx;
	}
	
	.modal-score {
		font-size: 36rpx;
		color: #776e65;
		margin-bottom: 40rpx;
	}
	
	.modal-score span {
		color: #f76c5e;
		font-weight: bold;
	}
	
	.modal-buttons {
		display: flex;
		gap: 20rpx;
		justify-content: center;
	}
	
	.modal-btn {
		padding: 15rpx 30rpx;
		border-radius: 8rpx;
		font-size: 30rpx;
		font-weight: bold;
		border: none;
		cursor: pointer;
		transition: background-color 0.2s ease;
	}
	
	.restart-btn {
		background-color: #8f7a66;
		color: white;
	}
	
	.exit-btn {
		background-color: #f76c5e;
		color: white;
	}
	
	/* 排行榜样式 */
	.ranking-header {
		padding: 20rpx;
		border-bottom: 1px solid #eee;
		text-align: center;
	}
	
	.ranking-header h3 {
		font-size: 36rpx;
		color: #776e65;
		margin: 0;
	}
	
	.ranking-list {
		height: calc(100% - 80rpx);
		overflow-y: auto;
		padding: 0;
		margin: 0;
		list-style: none;
	}
	
	.ranking-item {
		display: flex;
		align-items: center;
		padding: 20rpx;
		border-bottom: 1px solid #eee;
	}
	
	.rank-number {
		width: 60rpx;
		height: 60rpx;
		border-radius: 50%;
		background-color: #eee;
		color: #776e65;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 28rpx;
		font-weight: bold;
	}
	
	.top-rank {
		background-color: #f76c5e;
		color: white;
	}
	
	.rank-avatar {
		width: 70rpx;
		height: 70rpx;
		border-radius: 50%;
		overflow: hidden;
		margin: 0 20rpx;
	}
	
	.rank-avatar image {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}
	
	.rank-info {
		flex: 1;
	}
	
	.rank-name {
		font-size: 30rpx;
		font-weight: bold;
		color: #333;
		margin: 0 0 5rpx 0;
	}
	
	.rank-signature {
		font-size: 24rpx;
		color: #666;
		margin: 0;
	}
	
	.rank-score {
		font-size: 32rpx;
		font-weight: bold;
		color: #f76c5e;
		min-width: 80rpx;
		text-align: right;
	}
</style>
